package com.eva.service.system;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.eva.framework.mp.service.BaseService;
import com.eva.dao.system.SystemDepartmentMapper;
import com.eva.dao.system.model.SystemDepartment;
import com.eva.dao.system.model.SystemUser;
import com.eva.dao.system.model.SystemUserDepartment;
import org.springframework.context.annotation.Lazy;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

@Service
public class SystemDepartmentService extends BaseService<SystemDepartment, SystemDepartmentMapper> {

    @Resource
    private SystemUserService systemUserService;

    @Lazy
    @Resource
    private SystemUserDepartmentService systemUserDepartmentService;

    public SystemDepartmentService(SystemDepartmentMapper mapper, Environment environment) {
        super(mapper, environment);
    }

    /**
     * 查询用户部门
     * @param userId 用户ID
     * @return 部门列表
     */
    public List<SystemDepartment> findByUserId (Integer userId) {
        // 获取用户关联的部门主键集
        List<SystemUserDepartment> userDepartments = systemUserDepartmentService.findList(new SystemUserDepartment().setUserId(userId));
        if (userDepartments.isEmpty()) {
            return Collections.emptyList();
        }
        Set<Integer> departmentIds = userDepartments.stream()
                .map(SystemUserDepartment::getDepartmentId)
                .collect(Collectors.toSet());
        // 根据部门主键集查询出部门
        return this.findByIds(departmentIds);
    }

    /**
     * 统计部门人数
     *
     * @param id 部门ID
     * @return 部门总人数
     */
    public long count (Integer id) {
        // 获取子孙部门ID集
        Set<Integer> departmentIds = this.findChildIds(id);
        // 将当前部门ID添加到ID集，一并进行统计
        departmentIds.add(id);
        // 统计部门人数
        QueryWrapper<SystemUserDepartment> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda()
                .in(SystemUserDepartment::getDepartmentId, departmentIds)
                .eq(SystemUserDepartment::getDeleted, Boolean.FALSE);
        return systemUserDepartmentService.count(queryWrapper);
    }

    /**
     * 判断是否为部门负责人，适用于一个用户仅属于一个部门的情况
     *
     * @param userId 用户ID
     * @return 是否为部门负责人
     */
    public Boolean isLeader (Integer userId) {
        return systemUserDepartmentService.count(new SystemUserDepartment()
                .setUserId(userId)
                .setIsLeader(Boolean.TRUE)) > 0;
    }

    /**
     * 查询负责人
     *
     * @param departmentId 部门ID
     * @return 部门负责人
     */
    public SystemUser findLeader (Integer departmentId) {
        SystemUserDepartment userDepartment =  systemUserDepartmentService.findFirst(new SystemUserDepartment()
                .setDepartmentId(departmentId)
                .setIsLeader(Boolean.TRUE));
        if (userDepartment == null) {
            return null;
        }
        return systemUserService.findById(userDepartment.getUserId());
    }

    /**
     * 查询子孙部门ID集
     *
     * @param departmentId 部门ID
     * @return 子孙部门ID集
     */
    public Set<Integer> findChildIds(Integer departmentId) {
        Set<Integer> pool = new LinkedHashSet<>();
        this.fillChildIds(pool, Collections.singleton(departmentId));
        return pool;
    }

    /**
     * 填充子部门
     *
     * @param pool 子部门集合，用于记录子部门ID
     * @param parentIds 父部门ID集
     */
    private void fillChildIds(Set<Integer> pool, Set<Integer> parentIds) {
        QueryWrapper<SystemDepartment> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda()
                .in(SystemDepartment::getParentId, parentIds)
                .eq(SystemDepartment::getDeleted, Boolean.FALSE)
        ;
        Set<Integer> ids = this.findIds(queryWrapper);
        if (ids.size() > 0) {
            pool.addAll(ids);
            this.fillChildIds(pool, ids);
        }
    }
}
